package org.lwjgl.demo;


import org.joml.Matrix4f;
import org.lwjgl.demo.device.Camera;
import org.lwjgl.demo.device.ShaderProgram;
import org.lwjgl.demo.geometries.Cube;
import org.lwjgl.demo.geometries.Cylinder;
import org.lwjgl.demo.geometries.Sphere;
import org.lwjgl.demo.geometries.StarField;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryStack;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.system.MemoryUtil.NULL;

import org.joml.Vector3f;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
/**
 * description: 主程序
 *
 * @author zhoudy
 * @date 2025/10/29 20:33
 */
public class OpenGL {
    private long window;
    private ShaderProgram shader;
    private Camera camera;
    private Cube cube;
    private Cylinder cylinder;

    private StarField starField; //星空背景
    private Sphere sphere;
    // ==================== 新增：阴影映射相关字段 ====================
//    private ShaderProgram depthShader;
//    private int depthMapFBO;
//    private int depthMap;
//    private final int SHADOW_WIDTH = 1024;
//    private final int SHADOW_HEIGHT = 1024;
//
//    private boolean shadowsEnabled = true;  // 新增：阴影开关

    private float lastX = 400.0f;
    private float lastY = 300.0f;
    private boolean firstMouse = true;

    // ==================== 新增：时间跟踪变量 ====================
    private float deltaTime = 0.0f;
    private float lastFrame = 0.0f;

    public static void main(String[] args) {
        System.out.println("=== 3D 场景程序启动 -光照、纹理、相机控制 ===");
        System.out.println("操作系统: " + System.getProperty("os.name"));
        System.out.println("Java 版本: " + System.getProperty("java.version"));
        System.out.println("======================");

        // 检查是否是 macOS
        if (System.getProperty("os.name").toLowerCase().contains("mac")) {
            System.out.println("检测到 macOS，请确保使用 -XstartOnFirstThread 参数");
        }

        new OpenGL().run();
    }

    public void run() {
        System.out.println("程序开始执行，当前线程: " + Thread.currentThread().getName());

        try {
            init();
            loop();
        } catch (Exception e) {
            System.err.println("程序执行出错: " + e.getMessage());
            e.printStackTrace();
        } finally {
            cleanup();
        }
    }

    private void init() {
        System.out.println("1. 初始化窗口和OpenGL+GLFW...");
        initWindow();

        System.out.println("2. 初始化资源...");
        initResources();

        // ==================== 新增：初始化阴影映射 ====================
//        System.out.println("3. 初始化阴影映射...");
//        initShadowMapping();

        System.out.println("✅ 初始化完成");
    }
    private void initWindow() {

        // 设置错误回调
        GLFWErrorCallback.createPrint(System.err).set();

        // 初始化 GLFW
        if (!glfwInit()) {
            throw new IllegalStateException("无法初始化 GLFW");
        }

        // 配置窗口提示
        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

        // OpenGL 上下文配置
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

        // macOS 兼容性配置
        if (System.getProperty("os.name").toLowerCase().contains("mac")) {
            glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
        }

        System.out.println("2. 创建窗口...");
//        window = glfwCreateWindow(800, 600, "3D 场景 - 立方体、球体、圆柱体", NULL, NULL);
        window = glfwCreateWindow(1200, 800, "3D场景 - 立方体、球体、圆柱体、光照+纹理+相机控制", NULL, NULL);
        if (window == NULL) {
            throw new RuntimeException("窗口创建失败");
        }

        // 配置输入回调
        glfwSetKeyCallback(window, new GLFWKeyCallback() {
            @Override
            public void invoke(long window, int key, int scancode, int action, int mods) {
                OpenGL.this.keyCallback(window, key, scancode, action, mods);
            }
        });

        glfwSetCursorPosCallback(window, new GLFWCursorPosCallback() {
            @Override
            public void invoke(long window, double xpos, double ypos) {
                OpenGL.this.cursorPosCallback(window, xpos, ypos);
            }
        });

        glfwSetMouseButtonCallback(window, new GLFWMouseButtonCallback() {
            @Override
            public void invoke(long window, int button, int action, int mods) {
                OpenGL.this.mouseButtonCallback(window, button, action, mods);
            }
        });

        // ==================== 新增：隐藏光标并捕获 ====================
        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

        // 居中显示窗口
        centerWindow();

        // 创建 OpenGL 上下文
        glfwMakeContextCurrent(window);
        glfwSwapInterval(1); // 启用垂直同步
        glfwShowWindow(window);

        // 初始化 OpenGL
        GL.createCapabilities();
        // 检查OpenGL版本
        System.out.println("OpenGL版本: " + glGetString(GL_VERSION));

        // 配置全局 OpenGL 状态
        glEnable(GL_DEPTH_TEST);
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);

        System.out.println(" 显示窗口");
        glfwShowWindow(window);
        System.out.println("✅ 窗口初始化成功");

    }

    private void centerWindow() {
        // 使用 MemoryStack 进行内存操作
        MemoryStack stack = MemoryStack.stackPush();
        try {
            IntBuffer pWidth = stack.mallocInt(1);
            IntBuffer pHeight = stack.mallocInt(1);

            glfwGetWindowSize(window, pWidth, pHeight);

            GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

            glfwSetWindowPos(
                    window,
                    (vidmode.width() - pWidth.get(0)) / 2,
                    (vidmode.height() - pHeight.get(0)) / 2
            );
        } finally {
            stack.pop();
        }
    }

    private void initResources() {
        System.out.println("2.1 创建Phong光照着色器...");
        // 顶点着色器源代码 - JDK 1.8 兼容写法
//        String vertexShaderSource =
//                "#version 330 core\n" +
//                        "layout (location = 0) in vec3 aPos;\n" +
//                        "layout (location = 1) in vec3 aColor;\n" +
//                        "out vec3 ourColor;\n" +
//                        "uniform mat4 model;\n" +
//                        "uniform mat4 view;\n" +
//                        "uniform mat4 projection;\n" +
//                        "void main() {\n" +
//                        "    gl_Position = projection * view * model * vec4(aPos, 1.0);\n" +
//                        "    ourColor = aColor;\n" +
//                        "    // 根据颜色亮度决定星星大小（更亮的星星更大）\n" +
//                        "    float brightness = (ourColor.r + ourColor.g + ourColor.b) / 3.0;\n" +
//                        "    gl_PointSize = 6.0 + brightness * 7.0; // 大小在 2.0 到 5.0 之间\n" +
//                        "}";
        //顶点着色器
        String vertexShaderSource =
                "#version 330 core\n" +
                        "layout (location = 0) in vec3 aPos;\n" +
                        "layout (location = 1) in vec3 aNormal;\n" +
                        "layout (location = 2) in vec2 aTexCoord;\n" +
                        "out vec3 FragPos;\n" +
                        "out vec3 Normal;\n" +
                        "out vec2 TexCoord;\n" +
                        // ==================== 新增：光照空间位置 ====================
//                        "out vec4 FragPosLightSpace;\n" +

                        "uniform mat4 model;\n" +
                        "uniform mat4 view;\n" +
                        "uniform mat4 projection;\n" +
//                        "uniform mat4 lightSpaceMatrix;\n" + // 新增：光照空间矩阵
                        "void main() {\n" +
                        "    FragPos = vec3(model * vec4(aPos, 1.0));\n" +
                        "    Normal = mat3(transpose(inverse(model))) * aNormal;\n" +
                        "    TexCoord = aTexCoord;\n" +
//                        "    FragPosLightSpace = lightSpaceMatrix * vec4(FragPos, 1.0);\n" + // 新增：计算光照空间位置
                        "    gl_Position = projection * view * vec4(FragPos, 1.0);\n" +
                        // ==================== 修改：星星大小放大一倍 ====================
                        "    gl_PointSize = 10.0; // 从2.0增加到4.0，放大一倍\n" +
                        "}";

        // 片段着色器源代码
//        String fragmentShaderSource =
//                "#version 330 core\n" +
//                        "in vec3 ourColor;\n" +
//                        "out vec4 FragColor;\n" +
//                        "void main() {\n" +
//                        "    FragColor = vec4(ourColor, 1.0);\n" +
//                        "}\n";
        //主着色器
        String fragmentShaderSource =
                "#version 330 core\n" +
                        "struct Material {\n" +
                        "    sampler2D diffuse;\n" +
                        "    sampler2D specular;\n" +
                        "    float shininess;\n" +
                        "};\n" +
                        "struct Light {\n" +
                        "    vec3 position;\n" +
                        "    vec3 ambient;\n" +
                        "    vec3 diffuse;\n" +
                        "    vec3 specular;\n" +
                        "};\n" +
                        "in vec3 FragPos;\n" +
                        "in vec3 Normal;\n" +
                        "in vec2 TexCoord;\n" +
//                        "in vec4 FragPosLightSpace;\n" +  // 新增：从顶点着色器传入
                        "out vec4 FragColor;\n" +
                        "uniform vec3 viewPos;\n" +
                        "uniform Material material;\n" +
                        "uniform Light light1;\n" +  // 确保这里声明为light1
                        "uniform Light light2;\n" +  // 确保这里声明为light2
                        // ==================== 新增：阴影相关uniform ====================
//                        "uniform sampler2D shadowMap;\n" +  // 新增：阴影贴图
//                        "uniform mat4 lightSpaceMatrix;\n" +  // 新增：光照空间矩阵
//                        "uniform bool shadowsEnabled;\n" +   // 新增：阴影开关
//                        "\n" +
//                        "float ShadowCalculation(vec4 fragPosLightSpace) {\n" +
//                        "    // 执行透视除法\n" +
//                        "    vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;\n" +
//                        "    // 变换到[0,1]范围\n" +
//                        "    projCoords = projCoords * 0.5 + 0.5;\n" +
//                        "    // 获取最近深度\n" +
//                        "    float closestDepth = texture(shadowMap, projCoords.xy).r;\n" +
//                        "    // 当前片段深度\n" +
//                        "    float currentDepth = projCoords.z;\n" +
//                        "    // 检查当前片段是否在阴影中\n" +
//                        "    float shadow = currentDepth > closestDepth ? 1.0 : 0.0;\n" +
//                        "    \n" +
//                        "    return shadow;\n" +
//                        "}\n" +
                        "\n" +
                        "void main() {\n" +
                        "    // 环境光\n" +
                        "    vec3 ambient1 = light1.ambient * texture(material.diffuse, TexCoord).rgb;\n" +
                        "    vec3 ambient2 = light2.ambient * texture(material.diffuse, TexCoord).rgb;\n" +
                        "    \n" +
                        "    // 漫反射\n" +
                        "    vec3 norm = normalize(Normal);\n" +
                        "    vec3 lightDir1 = normalize(light1.position - FragPos);\n" +
                        "    vec3 lightDir2 = normalize(light2.position - FragPos);\n" +
                        "    float diff1 = max(dot(norm, lightDir1), 0.0);\n" +
                        "    float diff2 = max(dot(norm, lightDir2), 0.0);\n" +
                        "    vec3 diffuse1 = light1.diffuse * diff1 * texture(material.diffuse, TexCoord).rgb;\n" +
                        "    vec3 diffuse2 = light2.diffuse * diff2 * texture(material.diffuse, TexCoord).rgb;\n" +
                        "    \n" +
                        "    // 镜面反射\n" +
                        "    vec3 viewDir = normalize(viewPos - FragPos);\n" +
                        "    vec3 reflectDir1 = reflect(-lightDir1, norm);\n" +
                        "    vec3 reflectDir2 = reflect(-lightDir2, norm);\n" +
                        "    float spec1 = pow(max(dot(viewDir, reflectDir1), 0.0), material.shininess);\n" +
                        "    float spec2 = pow(max(dot(viewDir, reflectDir2), 0.0), material.shininess);\n" +
                        "    vec3 specular1 = light1.specular * spec1 * texture(material.specular, TexCoord).rgb;\n" +
                        "    vec3 specular2 = light2.specular * spec2 * texture(material.specular, TexCoord).rgb;\n" +
                        "    \n" +
//                        "    // ==================== 新增：阴影计算 ====================\n" +
//                        "    float shadow = 0.0;\n" +
//                        "    if (shadowsEnabled) {\n" +
////                        "        vec4 fragPosLightSpace = lightSpaceMatrix * vec4(FragPos, 1.0);\n" +
//                        "        shadow = ShadowCalculation(FragPosLightSpace);\n" +
//                        "    }\n" +
                        "    \n" +
                        "    // 合并所有光照分量（漫反射和镜面反射受阴影影响）\n" +
                        "    vec3 result = ambient1 + ambient2 + diffuse1 + diffuse2 + specular1 + specular2;\n" +
//                        "    vec3 ambient_total = ambient1 + ambient2;\n" +
//                        "    vec3 diffuse_total = diffuse1 + diffuse2;\n" +
//                        "    vec3 specular_total = specular1 + specular2;\n" +
//                        "    \n" +
//                        "    vec3 result = ambient_total + (1.0 - shadow) * (diffuse_total + specular_total);\n" +
                        "    FragColor = vec4(result, 1.0);\n" +
                        "}";

       // ==================== 新增：阴影映射着色器 ====================
//        System.out.println("2.3 创建阴影映射着色器...");

//        // 深度着色器 - 用于从光源视角渲染深度图
//        String depthVertexShaderSource =
//                "#version 330 core\n" +
//                        "layout (location = 0) in vec3 aPos;\n" +
//                        "uniform mat4 lightSpaceMatrix;\n" +
//                        "uniform mat4 model;\n" +
//                        "void main() {\n" +
//                        "    gl_Position = lightSpaceMatrix * model * vec4(aPos, 1.0);\n" +
//                        "}";
//
//        String depthFragmentShaderSource =
//                "#version 330 core\n" +
//                        "void main() {\n" +
//                        "    // gl_FragDepth = gl_FragCoord.z; // 自动写入深度\n" +
//                        "}";
//
//        depthShader = new ShaderProgram(depthVertexShaderSource, depthFragmentShaderSource);
//        System.out.println("✅ 深度着色器创建成功");

        // 创建着色器程序
        shader = new ShaderProgram(vertexShaderSource, fragmentShaderSource);
        System.out.println("✅ 着色器创建成功");

        // 初始化相机
        System.out.println("2.2 初始化第一人称相机...");
        camera = new Camera(
                new Vector3f(0.0f, 0.0f, 5.0f),
                new Vector3f(0.0f, 1.0f, 0.0f)
        );
        System.out.println("✅ 相机初始化成功");

        // 创建几何体
        System.out.println("2.3 创建带纹理的几何体...");
        cube = new Cube();
        System.out.println("✅ 立方体创建成功");
        sphere = new Sphere();
        System.out.println("✅ 球体创建成功");
        cylinder = new Cylinder();
        System.out.println("✅ 圆柱体创建成功");
        starField = new StarField(1000); // 1000颗星星
        System.out.println("✅ 星空背景创建成功");

        System.out.println("✅ 所有资源初始化成功");
    }

//    private void initShadowMapping() {
//        try {
//            System.out.println("初始化阴影映射...");
//
//            // 创建帧缓冲对象
//            depthMapFBO = glGenFramebuffers();
//
//            // 创建深度纹理
//            depthMap = glGenTextures();
//            glBindTexture(GL_TEXTURE_2D, depthMap);
//            glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
//                    SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, (java.nio.ByteBuffer) null);
//
//            // 设置纹理参数
//            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
//            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
//
//            float[] borderColor = { 1.0f, 1.0f, 1.0f, 1.0f };
//            glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
//
//            // 将深度纹理附加到帧缓冲区
//            glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
//            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
//            glDrawBuffer(GL_NONE);
//            glReadBuffer(GL_NONE);
//            glBindFramebuffer(GL_FRAMEBUFFER, 0);
//
//            System.out.println("✅ 阴影映射初始化成功");
//
//        } catch (Exception e) {
//            System.err.println("❌ 阴影映射初始化失败: " + e.getMessage());
//        }
//    }

    private void loop() {
        System.out.println("进入主循环 - 使用WASD移动, 鼠标视角, ESC退出");

        while (!glfwWindowShouldClose(window)) {
            // ==================== 新增：计算帧时间 ====================
            float currentFrame = (float) glfwGetTime();
            deltaTime = currentFrame - lastFrame;
            lastFrame = currentFrame;

            // 处理输入
            processInput();

            // 渲染
            renderFrame();

            // 交换缓冲区和处理事件
            glfwSwapBuffers(window);
            glfwPollEvents();
        }

        System.out.println("退出主渲染循环");
    }

    // ==================== 新增：处理键盘输入 ====================
    private void processInput() {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
            glfwSetWindowShouldClose(window, true);
        }

        // WASD移动控制
        if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
            camera.processKeyboard(GLFW_KEY_W, deltaTime);
        }
        if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
            camera.processKeyboard(GLFW_KEY_S, deltaTime);
        }
        if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
            camera.processKeyboard(GLFW_KEY_A, deltaTime);
        }
        if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
            camera.processKeyboard(GLFW_KEY_D, deltaTime);
        }

        // ==================== 新增：光照控制 ====================
        if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) {
            light1Intensity = Math.min(2.0f, light1Intensity + deltaTime);
            System.out.println("光源1强度: " + light1Intensity);
        }
        if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) {
            light1Intensity = Math.max(0.0f, light1Intensity - deltaTime);
            System.out.println("光源1强度: " + light1Intensity);
        }
        if (glfwGetKey(window, GLFW_KEY_3) == GLFW_PRESS) {
            light2Intensity = Math.min(2.0f, light2Intensity + deltaTime);
            System.out.println("光源2强度: " + light2Intensity);
        }
        if (glfwGetKey(window, GLFW_KEY_4) == GLFW_PRESS) {
            light2Intensity = Math.max(0.0f, light2Intensity - deltaTime);
            System.out.println("光源2强度: " + light2Intensity);
        }
        if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) {
            rotateLights = !rotateLights;
            System.out.println("光源旋转: " + (rotateLights ? "开启" : "关闭"));
        }

        // ==================== 新增：阴影开关控制 ====================
//        if (glfwGetKey(window, GLFW_KEY_T) == GLFW_PRESS) {
//            // 简单的防抖处理
//            try {
//                Thread.sleep(200);                                                  // 新增：防抖延迟
//            } catch (InterruptedException e) {}
//
//            shadowsEnabled = !shadowsEnabled;                                       // 新增：切换阴影开关
//            System.out.println("阴影效果: " + (shadowsEnabled ? "开启" : "关闭"));    // 新增：输出状态
//        }
    }

    private void renderFrame() {

        // ==================== 新增：第一步 - 渲染深度贴图 ====================
//        renderDepthMap();

        // 清除颜色和深度缓冲
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // ==================== 修改：确保使用正确的视口 ====================
//        glViewport(0, 0, 1200, 800);                                                // 修改：明确设置主渲染视口

        // 使用着色器程序
        shader.use();
        // ==================== 新增：设置阴影参数 ====================
//        // 设置阴影相关uniform
//        shader.setUniform("shadowsEnabled", shadowsEnabled);
//        shader.setUniform("shadowMap", 2); // 使用纹理单元2
//
//        // 绑定阴影贴图
//        glActiveTexture(GL_TEXTURE2);
//        glBindTexture(GL_TEXTURE_2D, depthMap);
//
//        // 计算光照空间矩阵（与深度渲染时相同）
//        float near_plane = 1.0f, far_plane = 10.0f;
//        Matrix4f lightProjection = new Matrix4f().ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
//        Vector3f lightPos = new Vector3f(3.0f, 3.0f, 3.0f);
//        Matrix4f lightView = new Matrix4f().lookAt(lightPos,
//                new Vector3f(0.0f, 0.0f, 0.0f), new Vector3f(0.0f, 1.0f, 0.0f));
//        Matrix4f lightSpaceMatrix = new Matrix4f();
//        lightProjection.mul(lightView, lightSpaceMatrix);
//
//        // ==================== 修复：将 Matrix4f 转换为 FloatBuffer ====================
//        try (MemoryStack stack = MemoryStack.stackPush()) {
//            FloatBuffer lightSpaceBuffer = stack.mallocFloat(16);
//            lightSpaceMatrix.get(lightSpaceBuffer);
//            shader.setUniformMatrix4("lightSpaceMatrix", lightSpaceBuffer);
//        }

        // ==================== 新增：设置光照参数 ====================
        setupLighting();
        // ==================== 新增：更新动态光照 ====================
        float time = (float) glfwGetTime();
        updateLighting(time);


        // ==================== 新增：设置材质参数 ====================
        setupMaterial();

        // 设置视图和投影矩阵
        Matrix4f view = camera.getViewMatrix();
        Matrix4f projection = new Matrix4f().perspective(
                (float) Math.toRadians(45.0f), 1200.0f / 800.0f, 0.1f, 100.0f
        );

        // 使用 MemoryStack 传递矩阵数据
        MemoryStack stack = MemoryStack.stackPush();
        try {
            FloatBuffer viewBuffer = stack.mallocFloat(16);
            FloatBuffer projectionBuffer = stack.mallocFloat(16);

            view.get(viewBuffer);
            projection.get(projectionBuffer);

            shader.setUniformMatrix4("view", viewBuffer);
            shader.setUniformMatrix4("projection", projectionBuffer);

            // ==================== 新增：设置相机位置（用于镜面反射计算） ====================
            shader.setUniform("viewPos", camera.getPosition().x, camera.getPosition().y, camera.getPosition().z);

//            float time2 = (float) glfwGetTime();

           // 1. 先渲染星空背景（使用单位矩阵）
            Matrix4f model = new Matrix4f(); // 单位矩阵，星空不动
            setModelMatrix(model);

            // 启用点平滑（让星星看起来更圆）
            glEnable(GL_POINT_SMOOTH);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            starField.render();
            glDisable(GL_BLEND);
            glDisable(GL_POINT_SMOOTH);

            // 2. 然后渲染三个几何体
            // 渲染立方体 (-1.5, 0, 0)
            model = new Matrix4f()
                    .translate(-1.2f, 0.0f, 0.0f)
                    .scale(0.5f)  // 缩小一半
                    .rotate((float) glfwGetTime(), 0.5f, 1.0f, 0.0f);
            setModelMatrix(model);
            cube.render();

            // 渲染球体 (0, 0, 0)
            model = new Matrix4f()
                    .translate(0.0f, 0.0f, 0.0f)
                    .scale(1.0f)  // 缩小一半
                    .rotate((float) glfwGetTime() * 0.5f, 0.0f, 1.0f, 0.0f);
            setModelMatrix(model);
            sphere.render();

            // 渲染圆柱体 (1.5, 0, 0)
            model = new Matrix4f()
                    .translate(1.2f, 0.0f, 0.0f)
                    .scale(0.5f)  // 缩小一半
                    .rotate((float) glfwGetTime() * 0.3f, 1.0f, 0.0f, 0.0f);
            setModelMatrix(model);
            cylinder.render();

        } finally {
            stack.pop();
        }

        // ==================== 修改：解绑阴影贴图 ====================
        glActiveTexture(GL_TEXTURE2);                                               // 修改：激活纹理单元2
        glBindTexture(GL_TEXTURE_2D, 0);                                            // 修改：解绑阴影贴图
    }


    // ==================== 修改：完全重写深度渲染方法 ====================
//    private void renderDepthMap() {
//        System.out.println("开始渲染深度贴图...");
//
//        // 保存当前状态
//        int[] originalViewport = new int[4];
//        glGetIntegerv(GL_VIEWPORT, originalViewport);
//
//        // 设置深度贴图渲染
//        glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
//        glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
//        glClear(GL_DEPTH_BUFFER_BIT);
//
//        // 启用深度测试（确保）
//        glEnable(GL_DEPTH_TEST);
//
//        // 从光源视角设置正交投影矩阵
//        float near_plane = 1.0f, far_plane = 10.0f;
//        Matrix4f lightProjection = new Matrix4f().ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
//
//        // 光源位置
//        Vector3f lightPos = new Vector3f(3.0f, 3.0f, 3.0f);
//        Matrix4f lightView = new Matrix4f().lookAt(lightPos,
//                new Vector3f(0.0f, 0.0f, 0.0f), new Vector3f(0.0f, 1.0f, 0.0f));
//
//        Matrix4f lightSpaceMatrix = new Matrix4f();
//        lightProjection.mul(lightView, lightSpaceMatrix);
//
//        // 使用深度着色器
//        depthShader.use();
//
//        try (MemoryStack stack = MemoryStack.stackPush()) {
//            FloatBuffer lightSpaceBuffer = stack.mallocFloat(16);
//            lightSpaceMatrix.get(lightSpaceBuffer);
//            depthShader.setUniformMatrix4("lightSpaceMatrix", lightSpaceBuffer);
//        }
//
//        // 渲染场景到深度贴图
//        renderSceneForDepth();
//
//        // 恢复状态 - 强制恢复窗口大小
//        glBindFramebuffer(GL_FRAMEBUFFER, 0);
//
//        // 获取当前窗口大小并设置视口
//        try (MemoryStack stack = MemoryStack.stackPush()) {
//            IntBuffer width = stack.mallocInt(1);
//            IntBuffer height = stack.mallocInt(1);
//            glfwGetWindowSize(window, width, height);
//            glViewport(0, 0, width.get(0), height.get(0));
//            System.out.println("恢复视口到窗口大小: " + width.get(0) + "x" + height.get(0));
//        }
//
//        // 重新启用主渲染需要的状态
//        glEnable(GL_DEPTH_TEST);
//        System.out.println("深度贴图渲染完成");
//    }
//
//    // 渲染场景到深度贴图（简化版，只渲染几何体）
//    private void renderSceneForDepth() {
//        float time = (float) glfwGetTime();
//        // ==================== 修改：禁用可能影响深度渲染的状态 ====================
//        glDisable(GL_BLEND);                                                        // 修改：深度渲染时禁用混合
//        glDisable(GL_POINT_SMOOTH);                                                 // 修改：深度渲染时禁用电平滑
//
//        MemoryStack stack = MemoryStack.stackPush();
//            // 渲染立方体
//            Matrix4f model = new Matrix4f()
//                    .translate(-1.5f, 0.0f, 0.0f)
//                    .scale(0.5f)
//                    .rotate(time, 0.5f, 1.0f, 0.0f);
//
//            FloatBuffer modelBuffer = stack.mallocFloat(16);
//            model.get(modelBuffer);
//            depthShader.setUniformMatrix4("model", modelBuffer);
//            cube.render();
//
//    }

    // ==================== 新增：设置光照参数方法 ====================

    // ==================== 新增：光照控制参数 ====================
    private float light1Intensity = 1.0f;
    private float light2Intensity = 1.0f;
    private boolean rotateLights = true;

    private void setupLighting() {
        // 第一个光源（白色主光源）
        shader.setLightUniform("light1", "position", 3.0f, 3.0f, 3.0f);
        shader.setLightUniform("light1", "ambient", 0.1f * light1Intensity, 0.1f * light1Intensity, 0.1f * light1Intensity);
        shader.setLightUniform("light1", "diffuse", 0.8f * light1Intensity, 0.8f * light1Intensity, 0.8f * light1Intensity);
        shader.setLightUniform("light1", "specular", 1.5f * light1Intensity, 1.5f * light1Intensity, 1.5f * light1Intensity);

        // 第二个光源（红色辅助光源）
        shader.setLightUniform("light2", "position", -3.0f, 2.0f, -2.0f);
        shader.setLightUniform("light2", "ambient", 0.05f * light2Intensity, 0.0f, 0.0f);
        shader.setLightUniform("light2", "diffuse", 0.6f * light2Intensity, 0.2f * light2Intensity, 0.2f * light2Intensity);
        shader.setLightUniform("light2", "specular", 1.2f * light2Intensity, 0.6f * light2Intensity, 0.6f * light2Intensity);
    }

    private void updateLighting(float time) {
        if (rotateLights) {
            // 让光源围绕场景旋转
            float radius = 4.0f;
            float light1X = (float) Math.cos(time * 0.5) * radius;
            float light1Z = (float) Math.sin(time * 0.5) * radius;
            shader.setLightUniform("light1", "position", light1X, 3.0f, light1Z);

            float light2X = (float) Math.cos(time * 0.3 + Math.PI) * radius * 0.7f;
            float light2Z = (float) Math.sin(time * 0.3 + Math.PI) * radius * 0.7f;
            shader.setLightUniform("light2", "position", light2X, 2.0f, light2Z);
        }
    }

    private void setupLightingDefault() {
//        // 第一个光源（白色）
//        shader.setUniform("light1.position", 2.0f, 2.0f, 2.0f);
//        shader.setUniform("light1.ambient", 0.2f, 0.2f, 0.2f);
//        shader.setUniform("light1.diffuse", 0.8f, 0.8f, 0.8f);
//        shader.setUniform("light1.specular", 1.0f, 1.0f, 1.0f);
//
//        // 第二个光源（红色）
//        shader.setUniform("light2.position", -2.0f, 1.0f, -1.0f);
//        shader.setUniform("light2.ambient", 0.1f, 0.0f, 0.0f);
//        shader.setUniform("light2.diffuse", 0.8f, 0.2f, 0.2f);
//        shader.setUniform("light2.specular", 1.0f, 0.5f, 0.5f);

        // ==================== 修改：增强光源的镜面反射强度 ====================
        // 第一个光源 - 增强镜面反射
        shader.setLightUniform("light1", "position", 3.0f, 3.0f, 3.0f);
        shader.setLightUniform("light1", "ambient", 0.1f, 0.1f, 0.1f);
        shader.setLightUniform("light1", "diffuse", 0.8f, 0.8f, 0.8f);
        shader.setLightUniform("light1", "specular", 1.5f, 1.5f, 1.5f); // 增强镜面反射

        // 第二个光源 - 也增强镜面反射
        shader.setLightUniform("light2", "position", -3.0f, 2.0f, -2.0f);
        shader.setLightUniform("light2", "ambient", 0.05f, 0.0f, 0.0f);
        shader.setLightUniform("light2", "diffuse", 0.6f, 0.2f, 0.2f);
        shader.setLightUniform("light2", "specular", 1.2f, 0.6f, 0.6f); // 增强镜面反射

        //System.out.println("✅ 光照设置完成（增强镜面反射）");
    }

    // ==================== 新增：设置材质参数方法 ====================
    private void setupMaterial() {
//        shader.setUniform("material.shininess", 32.0f);

        // ==================== 修改：调整材质反光度 ====================
        // 降低反光度让高光区域更大更明显
        shader.setMaterialUniform("material", "shininess", 16.0f); // 从32降到16
        // 纹理单元设置
        shader.setUniform("material.diffuse", 0);  // 对应GL_TEXTURE0
        shader.setUniform("material.specular", 1); // 对应GL_TEXTURE1

        //System.out.println("✅ 材质设置完成（反光度: 16.0）");
    }

    private void setModelMatrix(Matrix4f model) {
        MemoryStack stack = MemoryStack.stackPush();
        try {
            FloatBuffer modelBuffer = stack.mallocFloat(16);
            model.get(modelBuffer);
            shader.setUniformMatrix4("model", modelBuffer);
        } finally {
            stack.pop();
        }
    }

//    private void processInput() {
//        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
//            glfwSetWindowShouldClose(window, true);
//        }
//    }

    private void keyCallback(long window, int key, int scancode, int action, int mods) {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
            glfwSetWindowShouldClose(window, true);
        }
    }

    private void cursorPosCallback(long window, double xpos, double ypos) {
        if (firstMouse) {
            lastX = (float) xpos;
            lastY = (float) ypos;
            firstMouse = false;
        }

        float xoffset = (float) xpos - lastX;
        float yoffset = lastY - (float) ypos;
        lastX = (float) xpos;
        lastY = (float) ypos;

        camera.processMouseMovement(xoffset, yoffset);
    }

    private void mouseButtonCallback(long window, int button, int action, int mods) {
        // 可以在这里添加鼠标按钮处理逻辑
        if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
            System.out.println("左键点击");
        }
    }

    private void cleanup() {
        System.out.println("清理资源...");

        // 清理几何体
        if (cube != null) {
            cube.cleanup();
        }
        if (sphere != null) {
            sphere.cleanup();
        }
        if (cylinder != null) {
            cylinder.cleanup();
        }
        if (starField != null) {
            starField.cleanup();  // 清理星空资源
        }
        // 清理着色器
        if (shader != null) {
            shader.cleanup();
        }

        // 清理 GLFW
        if (window != NULL) {
            glfwFreeCallbacks(window);
            glfwDestroyWindow(window);
        }
        glfwTerminate();

        System.out.println("资源清理完成");
    }
}